package cn.lili.modules.dict.serviceimpl;

import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.dict.entity.dos.DictionaryLi;
import cn.lili.modules.dict.entity.vos.DictionaryVO;
import cn.lili.modules.dict.mapper.DictionaryMapper;
import cn.lili.modules.dict.service.DictionaryService;
import cn.lili.modules.page.entity.dos.Article;
import cn.lili.modules.page.entity.dos.ArticleCategory;
import cn.lili.modules.page.entity.enums.ArticleCategoryEnum;
import cn.lili.modules.page.entity.enums.ArticleEnum;
import cn.lili.modules.page.entity.vos.ArticleCategoryVO;
import cn.lili.modules.page.mapper.ArticleCategoryMapper;
import cn.lili.modules.page.service.ArticleCategoryService;
import cn.lili.modules.page.service.ArticleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 文章分类业务层实现
 *
 * @author pikachu
 * @since 2020-05-5 15:10:16
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, DictionaryLi> implements DictionaryService {

	/**
	 * 缓存
	 */
	@Autowired
	private Cache cache;
	/**
	 * 文章
	 */
	@Autowired
	private DictionaryService dictionaryService;
	/**
	 * 顶级父分类ID
	 */
	private String parentId = "0";
	/**
	 * 最大分类等级
	 */
	private int maxLevel = 2;

	@Override
	public DictionaryLi saveDictionaryLi(DictionaryLi dictionaryLi) {

		// 非顶级分类
		if (dictionaryLi.getParentId() != null && !parentId.equals(dictionaryLi.getParentId())) {
			DictionaryLi parent = this.getById(dictionaryLi.getParentId());
			if (parent == null) {
				throw new ServiceException(ResultCode.DICTIONARY_LI_PARENT_NOT_EXIST);
			}
			if (dictionaryLi.getLevel() >= maxLevel) {
				throw new ServiceException(ResultCode.DICTIONARY_LI_BEYOND_TWO);
			}
		}
		dictionaryLi.setType(ArticleCategoryEnum.OTHER.name());
		this.save(dictionaryLi);
		// 清除文章分类缓存
		this.clearCache();
		return dictionaryLi;
	}

	@Override
	public DictionaryLi updateDictionaryLi(DictionaryLi dictionaryLi) {
		// 非顶级分类校验是否存在
		if (!parentId.equals(dictionaryLi.getParentId())) {
			DictionaryLi parent = this.getById(dictionaryLi.getParentId());
			if (parent == null) {
				throw new ServiceException(ResultCode.DICTIONARY_LI_PARENT_NOT_EXIST);
			}
			// 替换catPath 根据path规则来匹配级别
			if (dictionaryLi.getLevel() >= maxLevel) {
				throw new ServiceException(ResultCode.DICTIONARY_LI_BEYOND_TWO);
			}
		}
		// 验证分类名称是否重复
		DictionaryLi category = this.getOne(
				new LambdaQueryWrapper<DictionaryLi>().eq(DictionaryLi::getDictName, dictionaryLi.getDictName()));
		if (category != null && !category.getId().equals(dictionaryLi.getId())) {
			throw new ServiceException(ResultCode.DICTIONARY_LI_NAME_EXIST);
		}
		if (this.updateById(dictionaryLi)) {
			// 清除文章分类
			this.clearCache();
			return category;
		}
		return null;
	}

	@Override
	public boolean deleteById(String id) {

		LambdaQueryWrapper<DictionaryLi> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(DictionaryLi::getParentId, id);

		// 查看文章分类下是否有分类
		if (this.count(lambdaQueryWrapper) > 0) {
			throw new ServiceException(ResultCode.DICTIONARY_LI_DELETE_ERROR);
		}

		// 查看文章分类下是否有文章
		// LambdaQueryWrapper<DictionaryLi> articleLambdaQueryWrapper = new
		// LambdaQueryWrapper<>();
		// articleLambdaQueryWrapper.eq(Article::getCategoryId, id);
		/*
		 * if (dictionaryService.count(articleLambdaQueryWrapper) > 0) { throw new
		 * ServiceException(ResultCode.DICTIONARY_LI_HAS_ARTICLE); }
		 */
		// 判断是否为默认的分类
		if (!this.getById(id).getType().equals(ArticleEnum.OTHER.name())) {
			throw new ServiceException(ResultCode.DICTIONARY_LI_NO_DELETION);
		}

		// 清除分类缓存
		this.clearCache();
		// 删除分类
		return this.removeById(id);
	}

	@Override
	public List<DictionaryVO> getDictionaryLiListVo(String dictCode) {
		return this.baseMapper.getDictionaryLiListVo(dictCode);
	}

	@Override
	public List<DictionaryVO> allChildren() {

		// 从缓存取所有的分类
		Object all = cache.get(CachePrefix.DICTIONARY_LI.getPrefix());
		List<DictionaryVO> articleCategories;
		if (all == null) {
			// 调用初始化分类缓存方法
			articleCategories = initCategory();
		} else {
			articleCategories = (List<DictionaryVO>) all;
		}
		return articleCategories;
	}

	/**
	 * 初始化所有文章分类
	 *
	 * @return 文章分类集合
	 */
	private List<DictionaryVO> initCategory() {
		List<DictionaryLi> articleCategories = this.list();
		List<DictionaryVO> tree = new ArrayList<>();
		articleCategories.forEach(item -> {
			if (item.getLevel() == 0) {
				DictionaryVO articleCategoryVO = new DictionaryVO(item);
				initChild(articleCategoryVO, articleCategories);
				tree.add(articleCategoryVO);
			}
		});
		// 对一级菜单排序
		tree.sort(new Comparator<DictionaryVO>() {
			@Override
			public int compare(DictionaryVO o1, DictionaryVO o2) {
				return o1.getSort().compareTo(o2.getSort());
			}
		});
		cache.put(CachePrefix.DICTIONARY_LI.getPrefix(), tree);

		return tree;
	}

	/**
	 * 递归初始化子树
	 *
	 * @param tree
	 *            树结构
	 * @param articleCategories
	 *            数据库对象集合
	 */
	private void initChild(DictionaryVO tree, List<DictionaryLi> articleCategories) {
		if (articleCategories == null) {
			return;
		}
		articleCategories.stream().filter(item -> (item.getParentId().equals(tree.getId()))).forEach(child -> {
			DictionaryVO childTree = new DictionaryVO(child);
			initChild(childTree, articleCategories);
			tree.getChildren().add(childTree);
		});
	}

	/**
	 * 清除缓存中的文章分类
	 */
	private void clearCache() {
		cache.remove(CachePrefix.DICTIONARY_LI.getPrefix());
	}

	@Autowired
	public void setArticleService(DictionaryService dictionaryService) {
		this.dictionaryService = dictionaryService;
	}
}